package xproto

import (
	"sync"
)

type Context struct {
	client IClient
	Access
	Status Status
}

// gMnger 默认列表
var (
	gMnger = make(map[string]*Context)
	gLock  sync.RWMutex
)

func (c *Context) sync() error {
	guid := c.DeviceNo
	if c.LinkType != LinkSignal {
		guid = contextID(c.DeviceNo, c.Session)
	}
	gLock.Lock()
	defer gLock.Unlock()
	if _, ok := gMnger[guid]; ok {
		return ErrObjectExist
	}
	gMnger[guid] = c
	return nil
}

func (c *Context) release() {
	guid := c.DeviceNo
	if c.LinkType != LinkSignal {
		guid = contextID(c.DeviceNo, c.Session)
	}
	gLock.Lock()
	delete(gMnger, guid)
	gLock.Unlock()
}

// SyncGet 从映射表中获取链接
func SyncGet(args ...string) *Context {
	guid := contextID(args...)
	gLock.RLock()
	defer gLock.RUnlock()
	if v, ok := gMnger[guid]; ok {
		return v
	}
	return nil
}

// SyncStop 停止服务
func SyncStop(args ...string) {
	if ctx := SyncGet(args...); ctx != nil {
		ctx.client.Request(ReqClose, nil, nil)
	}
}

// SyncSend 发送信息到设备
func SyncSend(cmd ReqCode, s interface{}, r interface{}, args ...string) error {
	if ctx := SyncGet(args...); ctx != nil {
		return ctx.client.Request(cmd, s, r)
	}
	return ErrObjectNoExist
}

// SyncWrite 发送信息到设备
func SyncWrite(s *RawData) error {
	return SyncSend(ReqWriteData, s, nil, s.DeviceNo, s.Session)
}

// StopAll 停止所有链接
func StopAll() {
	for _, v := range gMnger {
		v.client.Request(ReqClose, nil, nil)
	}
}

// AllAccess 所有接入信息
func AllAccess() (r []Access) {
	for _, v := range gMnger {
		r = append(r, v.Access)
	}
	return
}
